package de.unibi.comet.ac;

/** Distribution of alphabet characters (i.i.d. model). */
public class CharacterDistribution implements java.lang.Cloneable {
	private double[] probabilities;
	
	public CharacterDistribution() {
		probabilities = new double[256];
	}

	public CharacterDistribution(int[] frequencies) {
		probabilities = new double[256];
		double sum = 0.0;
		for (int i=0; i<frequencies.length; ++i) {
			sum+=frequencies[i];
		}
		for (int i=0; i<frequencies.length; ++i) {
			probabilities[i]=((double)frequencies[i])/sum;
		}
	}

	public void set(char c, double prob) {
		if (prob<0.0) throw new IllegalArgumentException("Probability must not be <0.0");
		probabilities[(int)c]=prob;
	}
	
	public double probability(char c) {
		return probabilities[(int)c];
	}
	
	/** Ensure that probabilities sum up to 1.0 by normalizing. */
	public void normalize() {
		double sum = 0.0;
		for (int i=0; i<probabilities.length; ++i) {
			sum+=probabilities[i];
		}
		if (sum<=0.0) throw new IllegalStateException("Normalization over empty distribution attempted");
		for (int i=0; i<probabilities.length; ++i) {
			probabilities[i]/=sum;
		}
	}
	
	public double[] getProbabilityArray() {
		double[] result = new double[256];
		System.arraycopy(probabilities, 0, result, 0, probabilities.length);
		return result;
	}
	
	public void add(CharacterDistribution dist) {
		// TODO: somehow improve performance
		for (int i=0; i<probabilities.length; ++i){
			probabilities[i]+=dist.probabilities[i];
		}
	}

	public void multiply(double factor) {
		// TODO: somehow improve performance
		for (int i=0; i<probabilities.length; ++i){
			probabilities[i]*=factor;
		}
	}

	@Override
	public CharacterDistribution clone() {
		CharacterDistribution clone = null;
		try {
			clone = (CharacterDistribution)super.clone();
			clone.probabilities = probabilities.clone();
		} catch (CloneNotSupportedException e) {
			assert(false);
		}
		return clone;
	}

}
